package iptux;

import baseclass.FileInfo;
import baseclass.LinkLabel;
import baseclass.MsgHistory;
import baseclass.PalInfo;
import iptux.Iptux;
import iptux.DialogFileTrans.MyProgressBarRenderer;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;

import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Vector;

import javax.swing.SwingConstants;
import javax.swing.ListSelectionModel;
import java.io.UnsupportedEncodingException;

/**
 * Title: class DialogPeel<br>
 * Description: DialogPeel class<br>
 * Copyright: MIT open source protocol<br>
 * @author cwll<cwll2009@126.com>
 * @version 1.0.0
 */
public class DialogPeer extends JDialog{

	private static final long serialVersionUID = 1L;
	public JTable table_FileToSend;
	private JTable table_FileReceive;
	JTextPane textPane_ChatInput;
	JTextPane textPane_ChatHistory;
	JSplitPane splitPane_mid;
	JSplitPane splitPane_left;
	
	IptuxUDPServer UDPServer;
	public PalInfo pal;
	public Iptux mainDlg;

	boolean MSGConfirmed = false;

	public ArrayList<FileInfo> rcvFileList = new ArrayList<FileInfo>();
	public ArrayList<FileInfo> sendFileList = new ArrayList<FileInfo>();
	ImageIcon imageRegularFile =  new ImageIcon("./bin/pixmaps/path/file.png");
	ImageIcon imageDir =  new ImageIcon("./bin/pixmaps/path/dir.png");
	JProgressBar progressBar_FileReceive = new JProgressBar(0,100);
	JProgressBar progressBar_FileSend = new JProgressBar(0,100);
	/**
	 * total size of all sent files
	 */
	private long sentFileSize = 0L;
	/**
	 * total size of all files to be send
	 */
	private long sendFileSize = 0L;
	/**
	 * total size of all sent files
	 */
	//private long receiveFileSize = 0L;
	/**
	 * total size of all files to be send
	 */
	private long receivedFileSize = 0L;
	//every chat dialog keep a split position in application run.
	//Saves only same one split position for all chat dialog when application exit.
	int midSplitPostion = 130;
	int leftSplitPostion = 150;
	
	final static int MaxRetryTimes = 3;
	final static Color ReveivedHeaderColor = Color.magenta;
	final static Color ReveivedTextColor = Color.BLUE;
	final static Color RECEIVED_FILE_COLOR = Color.GREEN;
	final static Color SendHeaderColor = Color.black;
	final static Color SendTextColor = Color.black;
	final static Color SENT_FILE_COLOR = Color.GREEN;
	final static Color SendErrorColor = Color.RED;
	final static int IPMSG_MSG_TYPE_SEND_MSG = 1;
	final static int IPMSG_MSG_TYPE_SEND_FILE = 2;
	final static int IPMSG_MSG_TYPE_RECEIVE_MSG = 3;
	final static int IPMSG_MSG_TYPE_RECEIVE_FILE = 4;
	final static int IPMSG_MSG_TYPE_SENG_MSG_FAIL = 5;
	/**
	 * Create the dialog.
	 * @param mainDlg the main frame 
	 * @param pal info of chat peer
	 */
	public DialogPeer(Iptux mainDlg,PalInfo pal){
		this.mainDlg = mainDlg;
		this.pal = pal;
		UDPServer = getUDPServer();
		midSplitPostion = mainDlg.configer.midSplitPostion;
		leftSplitPostion = mainDlg.configer.leftSplitPostion;
		setBounds(100, 100, 650, 500);
		{
			JPanel panel = new JPanel();
			getContentPane().add(panel, BorderLayout.CENTER);
			panel.setLayout(new BorderLayout(0, 0));
			{
				splitPane_mid = new JSplitPane();
				panel.add(splitPane_mid, BorderLayout.CENTER);
				{
					JPanel panel_Chat = new JPanel();
					
					splitPane_mid.setLeftComponent(panel_Chat);
					panel_Chat.setLayout(new BorderLayout(0, 0));
					{
						splitPane_left = new JSplitPane();
						splitPane_left.setSize(new Dimension(200, 0));
						splitPane_left.setOrientation(JSplitPane.VERTICAL_SPLIT);
						splitPane_left.setDividerLocation(60);
						panel_Chat.add(splitPane_left, BorderLayout.CENTER);
						{
							JPanel panel_ChatHistory = new JPanel();
							panel_ChatHistory.setMinimumSize(new Dimension(10, 200));
							panel_ChatHistory.setSize(new Dimension(200, 200));
							splitPane_left.setLeftComponent(panel_ChatHistory);
							panel_ChatHistory.setLayout(new BorderLayout(0, 0));
							{
								textPane_ChatHistory = new JTextPane();
								textPane_ChatHistory.setMinimumSize(new Dimension(6, 200));
								panel_ChatHistory.add(textPane_ChatHistory);
							}
						}
						{
							JPanel panel_ChatInput = new JPanel();
							splitPane_left.setRightComponent(panel_ChatInput);
							panel_ChatInput.setLayout(new BorderLayout(0, 0));
							{
								JPanel panel_3 = new JPanel();
								panel_ChatInput.add(panel_3, BorderLayout.NORTH);
								panel_3.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
								{
									JButton btnNewButton_2 = new JButton("clear history");
									panel_3.add(btnNewButton_2);
									btnNewButton_2.addMouseListener(new MouseAdapter() {
								         public void mouseClicked(MouseEvent e) {
								             clearChatHistory();
								          }       
								       });
								}
								{
									JButton btnNewButton_3 = new JButton("show history");
									panel_3.add(btnNewButton_3);
									btnNewButton_3.addMouseListener(new MouseAdapter() {
								         public void mouseClicked(MouseEvent e) {
								             showChatHistory();
								          }       
								       });
								}
							}
							{
								JPanel panel_3 = new JPanel();
								panel_ChatInput.add(panel_3, BorderLayout.CENTER);
								panel_3.setLayout(new BorderLayout(0, 0));
								{
									textPane_ChatInput = new JTextPane();
									panel_3.add(textPane_ChatInput, BorderLayout.CENTER);
									if(mainDlg.configer.enterKeySend){
										AbstractAction sendMsg = new AbstractAction() {
											@Override
											public void actionPerformed(ActionEvent e) {
												SendMsg();
											}
										};
										textPane_ChatInput.getInputMap().put(
												KeyStroke.getKeyStroke('\n', java.awt.event.InputEvent.CTRL_MASK),
												"send");
										textPane_ChatInput.getActionMap().put("send", sendMsg); 
									}
								}
							}
							{
								JPanel panel_3 = new JPanel();
								panel_ChatInput.add(panel_3, BorderLayout.SOUTH);
								FlowLayout fl_panel_3 = new FlowLayout(FlowLayout.RIGHT, 5, 5);
								panel_3.setLayout(fl_panel_3);
								{
									JButton btn_Close = new JButton("close");
									panel_3.add(btn_Close);
								}
								{
									JButton btn_Send = new JButton("send");
									btn_Send.addMouseListener(new MouseAdapter() {
								         public void mouseClicked(MouseEvent e) {
								             SendMsg();
								          }       
								       });
									panel_3.add(btn_Send);
								}
							}
						}
					}
				}
				{
					JPanel panel_File = new JPanel();
					splitPane_mid.setRightComponent(panel_File);
					panel_File.setLayout(new BorderLayout(0, 0));
					{
						JPanel panel_FileReceive = new JPanel();
						panel_FileReceive.setPreferredSize(new Dimension(10, 50));
						panel_FileReceive.setMinimumSize(new Dimension(10, 50));
						panel_File.add(panel_FileReceive, BorderLayout.CENTER);
						panel_FileReceive.setLayout(new BorderLayout(0, 0));
						{
							JPanel panel_FileReceiceList = new JPanel();
							panel_FileReceiceList.setSize(new Dimension(0, 50));
							panel_FileReceiceList.setPreferredSize(new Dimension(10, 50));
							panel_FileReceive.add(panel_FileReceiceList, BorderLayout.CENTER);
							panel_FileReceiceList.setLayout(new BorderLayout(0, 0));
							{
								progressBar_FileReceive.setIndeterminate(true);
								progressBar_FileReceive.setValue(30);
								progressBar_FileReceive.setIndeterminate(false);
								progressBar_FileReceive.setPreferredSize(new Dimension(0,4));
								panel_FileReceiceList.add(progressBar_FileReceive, BorderLayout.NORTH);
								String[] columnNames = {"", "filename", "size" ,"Obj"};
								String[][] tableData = new String[1][5];
								noEditTableModel receiveModel = new noEditTableModel(tableData, columnNames);
								table_FileReceive = new JTable();
								table_FileReceive.setModel(receiveModel);
								table_FileReceive.getColumn("").setCellRenderer(new ImageTableCellRenderer());
								
								//table_FileReceive = new JTable(tableData,columnNames);
								table_FileReceive.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
								//ImageTableCellRenderer renderer = new ImageTableCellRenderer();
								//table_FileReceive.setDefaultRenderer(Object.class, renderer);
								//DefaultTableModel model = new noEditTableModel(tableData, columnNames);
								//table_FileReceive.setModel(model);
								JScrollPane scrollPane = new JScrollPane(table_FileReceive);
								panel_FileReceiceList.add(scrollPane, BorderLayout.CENTER);
								setTableColumnWidth(table_FileReceive,3,0);
								setTableColumnWidth(table_FileReceive,0,20);
							}
						}
						{
							JPanel panel_FileReceiveControl = new JPanel();
							panel_FileReceive.add(panel_FileReceiveControl, BorderLayout.NORTH);
							panel_FileReceiveControl.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5));
							{
								JLabel label = new JLabel("file receive");
								label.setHorizontalTextPosition(SwingConstants.LEFT);
								panel_FileReceiveControl.add(label,FlowLayout.LEFT);
							}
							{
								JButton button = new JButton("Accept");
								panel_FileReceiveControl.add(button);
								button.addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent arg0) {
										saveAllFile();
									}
								});
							}
							{
								JButton button = new JButton("Refuse all");
								panel_FileReceiveControl.add(button);
								button.addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent arg0) {
										refuseAllFile();
									}
								});
							}
							{
								JButton button = new JButton("Save to");
								panel_FileReceiveControl.add(button);
								button.addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent arg0) {
										String saveFolder = chooseFileSaveDir();
										saveAllFile(saveFolder);
									}
								});
							}
						}
					}
					{
						JPanel panel_FileSend = new JPanel();
						panel_FileSend.setPreferredSize(new Dimension(0,160));
						panel_File.add(panel_FileSend, BorderLayout.SOUTH);
						panel_FileSend.setLayout(new BorderLayout(0, 0));
						{
							JPanel panel_FileSendControl = new JPanel();
							panel_FileSend.add(panel_FileSendControl, BorderLayout.NORTH);
							panel_FileSendControl.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5));
							{
								JLabel lblNewLabel = new JLabel("file send");
								panel_FileSendControl.add(lblNewLabel,FlowLayout.LEFT);
							}
							{
								JButton btnNewButton_4 = new JButton("Status");
								panel_FileSendControl.add(btnNewButton_4);
							}
							{
								JButton btnNewButton_5 = new JButton("File");
								panel_FileSendControl.add(btnNewButton_5);
								btnNewButton_5.addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent arg0) {
										addFileToSendList();
									}
								});
							}
/*							{
								JButton btnNewButton_5 = new JButton("Folder");
								panel_FileSendControl.add(btnNewButton_5);
								btnNewButton_5.addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent arg0) {
										addFileToSendList(JFileChooser.DIRECTORIES_ONLY);
									}
								});
							}*/
							{
								JButton btnNewButton_5 = new JButton("Cancel");
								panel_FileSendControl.add(btnNewButton_5);
								btnNewButton_5.addActionListener(new ActionListener() {
									public void actionPerformed(ActionEvent arg0) {
										clearSendList();
									}
								});
							}
						}
						{
							JPanel panel_FileSendList = new JPanel();
							panel_FileSendList.setPreferredSize(new Dimension(10, 50));
							panel_FileSend.add(panel_FileSendList, BorderLayout.CENTER);
							panel_FileSendList.setLayout(new BorderLayout(0, 0));
							{
								progressBar_FileSend.setIndeterminate(true);
								progressBar_FileSend.setValue(30);
								progressBar_FileSend.setIndeterminate(false);
								progressBar_FileSend.setPreferredSize(new Dimension(0,4));
								panel_FileSendList.add(progressBar_FileSend, BorderLayout.NORTH);
								String[] columnNames = {"","filename", "size", "full path","obj"};
								String[][] tableData = new String[1][5];
								noEditTableModel sendModel = new noEditTableModel(tableData, columnNames);
								table_FileToSend = new JTable();
								table_FileToSend.setModel(sendModel);
								table_FileToSend.getColumn("").setCellRenderer(new ImageTableCellRenderer());
								table_FileToSend.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
								JScrollPane scrollPane = new JScrollPane(table_FileToSend);
								panel_FileSendList.add(scrollPane, BorderLayout.CENTER);
								setTableColumnWidth(table_FileToSend,4,0);
								setTableColumnWidth(table_FileToSend,0,20);
							}
						}
					}
				}
			}
		}
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowOpened(WindowEvent e) {
				setSplitPostion();
			}
			@Override
		    public void windowActivated(WindowEvent e) {
				setSplitPostion();
		    }
			@Override
		    public void windowClosing(WindowEvent e) {
				saveSplitPostion();
		    }
		});
		initialize();

	}
	
	/**
	 * Do initialize 
	 */
	private void initialize(){
		textPane_ChatHistory.setEditable(false);
		setSplitPostion();	
		{
			JPopupMenu popup = new JPopupMenu();
			JMenuItem menuItem;
			menuItem = new JMenuItem("remove");
			menuItem.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent arg0) {
					removeFileFromRcvTable(arg0);
				}
			});
			popup.add(menuItem);
			MouseListener popupListener = new PopupListener(popup);
			table_FileReceive.addMouseListener(popupListener);
		}

		{
			JPopupMenu popup = new JPopupMenu();
			JMenuItem menuItem;
			menuItem = new JMenuItem("remove");
			menuItem.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent arg0) {
					removeFileFromSendTable(arg0);
				}
			});
			popup.add(menuItem);
			MouseListener popupListener = new PopupListener(popup);
			table_FileToSend.addMouseListener(popupListener);
		}
		FileReceiveUIUpdate fileRcvUiUpdate = new FileReceiveUIUpdate();
		new Thread(fileRcvUiUpdate).start();
	}
	
	/**
	 * show a file save dialog.
	 * @return
	 */
	public String chooseFileSaveDir(){
		JFileChooser fileDialog = new JFileChooser();
		fileDialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		fileDialog.setDialogTitle("Select a folder to save received files to");
		fileDialog.setMultiSelectionEnabled(false);
		int flag = fileDialog.showSaveDialog(this);
		File file = null;
		if(flag == JFileChooser.APPROVE_OPTION){   
			file = fileDialog.getSelectedFile();    
         }
		if(file == null){
			return null;
		}
		return file.getPath();
	}
	
	/**
	 * File receive table's
	 * @param arg0
	 */
	private void removeFileFromRcvTable(ActionEvent arg0){
		int selectedRowIndex = table_FileReceive.getSelectedRow();
		FileInfo file  = (FileInfo)(table_FileReceive.getValueAt(selectedRowIndex, 3));
		removeFileFromTable(table_FileReceive,selectedRowIndex);
		rcvFileList.remove(file);
	}
	
	private void removeFileFromSendTable(ActionEvent arg0){
		int selectedRowIndex = table_FileToSend.getSelectedRow();
		FileInfo file  = (FileInfo)(table_FileToSend.getValueAt(selectedRowIndex, 4));
		removeFileFromTable(table_FileToSend,selectedRowIndex);
		sendFileList.remove(file);
	}
	
	
	class PopupListener extends MouseAdapter {
        JPopupMenu popup;
 
        PopupListener(JPopupMenu popupMenu) {
            popup = popupMenu;
        }
 
        public void mousePressed(MouseEvent e) {
            //maybeShowPopup(e);
        	//showPopup(e);
        }
 
        public void mouseReleased(MouseEvent e) {
        	if(e.getButton() == MouseEvent.BUTTON3){
        		showPopup(e);
        	}
        	//showPopup(e);
        }
 
        private void showPopup(MouseEvent e) {
        	popup.show(e.getComponent(), e.getX(), e.getY());
        }
        
        public void mouseDragged(MouseEvent e){
        	//
        }

    }
	
	private void setSplitPostion(){
		splitPane_mid.setDividerLocation(midSplitPostion);
		splitPane_left.setDividerLocation(leftSplitPostion);
	}
	
	private void saveSplitPostion(){
		midSplitPostion = splitPane_mid.getDividerLocation();
		leftSplitPostion = splitPane_left.getDividerLocation();
		mainDlg.configer.midSplitPostion = midSplitPostion;
		mainDlg.configer.leftSplitPostion = leftSplitPostion;
	}
	
	public long getSentFileSize(){
		return this.sentFileSize;
	}
	
	/**
	 * add new sent size to the total sent files size
	 * @param size
	 * @return total sent size
	 */
	public long addSentFileSize(long size){
		this.sentFileSize += size;
		return this.sentFileSize;
	}
	
	/**
	 * Send the string message in the input textpane
	 * Send the info of files in send table 
	 */	
	private void SendMsg(){		
		SendTextMSG();
		SendFileMsg();
	}
	
	/**
	 * Send the string message in the input textpane
	 * @return is the peer send back a confirm echo
	 */	
	private boolean SendTextMSG(){
		if (textPane_ChatInput.getText().length() == 0)
			return true;
        MessageSender MSGSender = new MessageSender();
        new Thread(MSGSender).start();
        this.appendMsgToHistory(textPane_ChatInput.getText(), IPMSG_MSG_TYPE_SEND_MSG);
		this.textPane_ChatInput.setText("");
		return MSGConfirmed;
	}
	
	/**
	 * Append String to JTextPane control
	 * @param pane The control to display the String
	 * @param text The String to display
	 * @param color The color of String
	 */
	public void TextPaneAppendText(JTextPane pane,String text,Color color){
		Document doc = pane.getDocument();
		SimpleAttributeSet attrset=new SimpleAttributeSet();
		StyleConstants.setForeground(attrset,color);
		try {
			//System.out.println(text);
			text = text.replace("\r", "\n");
			doc.insertString(doc.getLength(),text,attrset);
			//System.out.println(doc.getText(0, doc.getLength()));
		} catch (BadLocationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
	}
	
	/**
	 * MessageSender is a multi thread method to send message to peer. It send the message and 
	 * wait for 10 seconds, if the peer don't send a confirm echo, it will send the message again.
	 * This method repeat the above action three times when a sent message is not responsed.
	 * @author ubuntu
	 *
	 */
    class MessageSender implements Runnable{
    	public void run(){
    		int Command =  StaticConsts.IPMSG_SENDMSG | StaticConsts.IPMSG_SENDCHECKOPT;
    		//int PacketNum = UDPServer.PacketNum;
    		
            for(int i = 0; i < MaxRetryTimes; i++){
            	UDPServer.SendMSG(pal.ipv4, textPane_ChatInput.getText(),Command/*,mainDlg.PacketNum*/);

            	try{
/*            	    Thread thread = Thread.currentThread();
            	    thread.sleep(2000);//暂停2秒后程序继续执行
*/            	    Thread.sleep(2000);
            	}catch (InterruptedException e) {
            	    // TODO Auto-generated catch block
            	    e.printStackTrace();
            	}
            	if ( pal.rpacketn == pal.rpacketn){
            		MSGConfirmed = true;
            		return;
            	}
            }            
            TextPaneAppendText(textPane_ChatHistory,"Message sent, but no response. \n",SendErrorColor);
    	}
    }
	
    /**
     * Get the UDP server of the peer attach to. If the local machine have more than one IP address, the main 
     * thread of the program will keep a UDP server for each IP address.
     * @return
     */
	public IptuxUDPServer getUDPServer()	{
		IptuxUDPServer UDPServer = null;
		String ServerNet = null;
		String Net = pal.ipv4.substring(0,pal.ipv4.lastIndexOf("."));
		for (IptuxUDPServer Server:this.mainDlg.UDPServerList){
			ServerNet = Server.localhost.substring(0,Server.localhost.lastIndexOf("."));
			if (Net.equals(ServerNet)){
				UDPServer = Server;
			}
		}
		return UDPServer;
	}
	
    /**
     * Get the UDP server of the peer attach to. If the local machine have more than one IP address, the main 
     * thread of the program will keep a UDP server for each IP address.
     * @return
     */
	public IptuxTCPServer getTCPServer()	{
		IptuxTCPServer TCPServer = null;
		String ServerNet = null;
		String Net = pal.ipv4.substring(0,pal.ipv4.lastIndexOf("."));
		for (IptuxTCPServer Server:this.mainDlg.TCPServerList){
			ServerNet = Server.localhost.substring(0,Server.localhost.lastIndexOf("."));
			if (Net.equals(ServerNet)){
				TCPServer = Server;
			}
		}
		return TCPServer;
	}
	
	/**
	 * Process the received message.
	 * @param data The message with the IPMSG header.
	 * @return
	 */
	public boolean ReceiveMSG(String data){
    	String[] DataList = data.split(":");
    	String Msg = "";
/*    	int PacketID = Integer.parseInt(data.split(":")[1]);
    	if (PacketID <= pal.packetn)
    		return true;
    	pal.packetn = PacketID;*/
    	for (int index = 5 ; index < DataList.length; index++){
    		Msg = Msg + DataList[index];
    	}
    	Msg = Msg.trim();
		appendMsgToHistory(Msg,IPMSG_MSG_TYPE_RECEIVE_MSG);
		
		
/*		int commandno = Integer.parseInt(data.split(":")[4]);
		int commandopt = StaticConsts.GET_OPT(commandno);*/
		this.mainDlg.AnimatePal(pal);
		return true;
	}
	
	/**
	 * Append chat history to the history txtpane.
	 * @param Msg the message string
	 * @param MsgType  message type int
	 */
	public void appendMsgToHistory(String Msg,int MsgType){

		switch (MsgType ){
			case IPMSG_MSG_TYPE_SEND_MSG:{
		        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		        String datetime = dateformat.format(new Date());
				String msgHeader = datetime + " " +this.mainDlg.SelfInfo.name + " :\n";
				TextPaneAppendText(this.textPane_ChatHistory,msgHeader,SendHeaderColor);
				String msgContent = textPane_ChatInput.getText() + "\n";
				TextPaneAppendText(this.textPane_ChatHistory,msgContent,SendTextColor);
				break;
			}
			case IPMSG_MSG_TYPE_SEND_FILE:{
				TextPaneAppendText(textPane_ChatHistory,Msg + "\n",SENT_FILE_COLOR);
				break;
			}
			case IPMSG_MSG_TYPE_RECEIVE_MSG:{
				SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String datetime = dateformat.format(new Date());		
				String msgHeader = datetime + " " +this.pal.name + " :\n";
				TextPaneAppendText(textPane_ChatHistory,msgHeader,ReveivedHeaderColor);
				TextPaneAppendText(textPane_ChatHistory,Msg + "\n",ReveivedTextColor);
				break;
			}
			case IPMSG_MSG_TYPE_RECEIVE_FILE:{
				String sendName = Msg.split(";`;`")[0];
				String saveName = Msg.split(";`;`")[1];
				//File saveFile = new File(saveName);
				TextPaneAppendText(textPane_ChatHistory,"File ",ReveivedTextColor);
				TextPaneAppendText(textPane_ChatHistory,sendName,RECEIVED_FILE_COLOR);
				TextPaneAppendText(textPane_ChatHistory," receive complete. Saved in ",ReveivedTextColor);
				//add a hyper link label to enable user to click to open the saved folder.
				LinkLabel label = new LinkLabel(saveName,saveName);
				textPane_ChatHistory.setCaretPosition(textPane_ChatHistory.getDocument().getLength());
				textPane_ChatHistory.insertComponent(label);
	
				TextPaneAppendText(textPane_ChatHistory,"\n",ReveivedTextColor);
				break;
			}
			case IPMSG_MSG_TYPE_SENG_MSG_FAIL:{
				TextPaneAppendText(textPane_ChatHistory,Msg + "\n",SendErrorColor);
				break;
			}
		}
		if(mainDlg.msgLogger != null){
			mainDlg.msgLogger.addLogger(MsgType, Msg, pal);
		}

	}
	/**
	 * Append chat history to the history txtpane. only used to show saved chat history
	 * from database.
	 * @param Msg the message string
	 * @param MsgType  message type int
	 * @param dateTime date time of msg
	 */
	public void appendMsgToHistory(String Msg,int MsgType,Date time){

        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String datetime = dateformat.format(time);
		switch (MsgType ){
			case IPMSG_MSG_TYPE_SEND_MSG:{
				String msgHeader = datetime + " " +this.mainDlg.SelfInfo.name + " :\n";
				TextPaneAppendText(this.textPane_ChatHistory,msgHeader,SendHeaderColor);
				String msgContent = Msg + "\n";
				TextPaneAppendText(this.textPane_ChatHistory,msgContent,SendTextColor);
				break;
			}
			case IPMSG_MSG_TYPE_SEND_FILE:{
				TextPaneAppendText(textPane_ChatHistory,datetime + " :" + Msg + "\n",SENT_FILE_COLOR);
				break;
			}
			case IPMSG_MSG_TYPE_RECEIVE_MSG:{	
				String msgHeader = datetime + " " +this.pal.name + " :\n";
				TextPaneAppendText(textPane_ChatHistory,msgHeader,ReveivedHeaderColor);
				TextPaneAppendText(textPane_ChatHistory,Msg + "\n",ReveivedTextColor);
				break;
			}
			case IPMSG_MSG_TYPE_RECEIVE_FILE:{
				String sendName = Msg.split(";`;`")[0];
				String saveName = Msg.split(";`;`")[1];
				//File saveFile = new File(saveName);
				TextPaneAppendText(textPane_ChatHistory,datetime + " :File ",ReveivedTextColor);
				TextPaneAppendText(textPane_ChatHistory,sendName,RECEIVED_FILE_COLOR);
				TextPaneAppendText(textPane_ChatHistory," receive complete. Saved in ",ReveivedTextColor);
				//add a hyper link label to enable user to click to open the saved folder.
				LinkLabel label = new LinkLabel(saveName,saveName);
				textPane_ChatHistory.setCaretPosition(textPane_ChatHistory.getDocument().getLength());
				textPane_ChatHistory.insertComponent(label);
	
				TextPaneAppendText(textPane_ChatHistory,"\n",ReveivedTextColor);
				break;
			}
			case IPMSG_MSG_TYPE_SENG_MSG_FAIL:{
				TextPaneAppendText(textPane_ChatHistory,datetime + ":" + Msg + "\n",SendErrorColor);
				break;
			}
		}


	}
	public void clearChatHistory(){
		mainDlg.msgLogger.clearPalLogger(pal);
		textPane_ChatHistory.setText("");
	}
	
	public void showChatHistory(){
		textPane_ChatHistory.setText("");
		ArrayList<MsgHistory> history = mainDlg.msgLogger.getLogger(pal.ipv4);
		for(MsgHistory item:history){
			appendMsgToHistory(item.msg,item.msgType,item.dateTime);
		}
	}
	
	public void addFileToSendList(){
		JFileChooser fileChooser = new JFileChooser(System.getProperty("user.home"));
		fileChooser.setMultiSelectionEnabled(true);
		fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
		fileChooser.showOpenDialog(this);
		File[] files = fileChooser.getSelectedFiles();
		for (File file:files){
			FileInfo fInfo = new FileInfo();
			fInfo.fileown = pal.ipv4;
			fInfo.filepath = file.getAbsolutePath();
			if(file.isFile()){
				fInfo.fileattr = Integer.toString(StaticConsts.IPMSG_FILE_REGAR, 16);
				fInfo.filesize = file.length();
			}else{
				fInfo.fileattr = Integer.toString(StaticConsts.IPMSG_FILE_DIR, 16);
				fInfo.filesize = Utils.getDirSize(file);
			}
			sendFileList.add(fInfo);
		}
		updateFileSendTable();
	}

	public void addFolderToSendList(){

	}

	public void clearSendList(){
		sendFileList.clear();
		updateFileSendTable();
	}
	
	/**
	 * update UI of the file receive table.
	 */
	public void updateFileSendTable(){
		int fileattr;
		File file;
		DefaultTableModel sendModel = (DefaultTableModel)(table_FileToSend.getModel());
		Vector dataVector =  sendModel.getDataVector();
		dataVector.clear();
		for(int index = 0 ; index < this.sendFileList.size() ; index++){
			Vector<Object> rowVector = new Vector<Object>();
			FileInfo fileInfo = sendFileList.get(index);
			//System.out.println("File attr is:" + fileInfo.fileattr);
			fileattr = Integer.valueOf(fileInfo.fileattr,16);
			if (fileattr == StaticConsts.IPMSG_FILE_REGAR){
				rowVector.add(imageRegularFile);
			}else{
				rowVector.add(imageDir);
			}
			file = new File(fileInfo.filepath);
			rowVector.add(file.getName());
			rowVector.add(Utils.longSizeToUISize(fileInfo.filesize));
			rowVector.add(fileInfo.filepath);
			rowVector.add(fileInfo);
			dataVector.add(rowVector);
		}
		table_FileToSend.updateUI();
	}
	
	private boolean SendFileMsg(){
		if(sendFileList.size() == 0)
			return true;
		this.UDPServer.SendFileInfo(sendFileList,this.pal.ipv4);
		return true;
	}
	
	
	/**
	 * Add file info to file receive list.
	 * @param fileInfo FileInfo handler to add
	 */
	public void appendRcvFile(FileInfo fileInfo){
		rcvFileList.add(fileInfo);
		mainDlg.rcvFileList.add(fileInfo);
	}
	
	/**
	 * update UI of the file receive table.
	 */
	public void UpdateFileRcvTable(){
		DefaultTableModel sendModel = (DefaultTableModel)(table_FileReceive.getModel());
		Vector dataVector =  sendModel.getDataVector();
		dataVector.clear();
		int fileattr;
		for(int index = 0 ; index < this.rcvFileList.size() ; index++){
			Vector<Object> rowVector = new Vector<Object>();
			FileInfo fileInfo = rcvFileList.get(index);
			//System.out.println("File attr is:" + fileInfo.fileattr);
			fileattr = Integer.valueOf(fileInfo.fileattr,16);
			if (fileattr == StaticConsts.IPMSG_FILE_REGAR){
				rowVector.add(imageRegularFile);
			}else{
				rowVector.add(imageDir);
			}
			rowVector.add(fileInfo.filepath);
			rowVector.add(Utils.longSizeToUISize(fileInfo.filesize));
			rowVector.add(fileInfo);
			dataVector.add(rowVector);
		}
		table_FileReceive.updateUI();
/*		int rowCount;
		//System.out.println("rcvFileList count is :" + rcvFileList.size());
		if(rcvFileList.size() == 0){
			rowCount = 1;
		}else{
			rowCount = this.rcvFileList.size();
		}
		Object[][] tableMode = new Object[rowCount][4];
		int fileattr;
		for(int index = 0 ; index < this.rcvFileList.size() ; index++){
			FileInfo fileInfo = rcvFileList.get(index);
			//System.out.println("File attr is:" + fileInfo.fileattr);
			fileattr = Integer.valueOf(fileInfo.fileattr,16);
			if (fileattr ==StaticConsts.IPMSG_FILE_REGAR){
				tableMode[index][0] = imageRegularFile;
			}else{
				tableMode[index][0] = imageDir;
			}
			tableMode[index][1] = fileInfo.filepath;
			tableMode[index][2] = Utils.longSizeToUISize(fileInfo.filesize);
			tableMode[index][3] = fileInfo;
		}
		String[] columnNames = {"", "filename", "size" ,""};
		DefaultTableModel model = new noEditTableModel(tableMode, columnNames);
		table_FileReceive.setModel(model);
		setTableColumnWidth(table_FileReceive,3,0);
		setTableColumnWidth(table_FileReceive,0,20);*/
	}
	
	/**
	 * delete file in receive or send table
	 * @param table table object
	 * @param file  file object
	 * @param fileIndex  FileInfo 's index in column
	 */
	public void removeFileFromTable(JTable table,FileInfo file,int fileIndex){
		int rowCount = table.getRowCount();
		int rowPosition = -1;
		for(int row = 0 ; row < rowCount ; row++){
			FileInfo fileInfo = (FileInfo)(table.getValueAt(row, fileIndex));
			if(fileInfo == file){
				rowPosition = row;
			}
		}
		if(rowPosition != -1){
			DefaultTableModel df = (DefaultTableModel) table.getModel();
			df.removeRow(rowPosition);
		}
	}
	
	/**
	 * delete a row in receive or send table
	 * @param table table object
	 * @param rowIndex  row 's index
	 */
	public void removeFileFromTable(JTable table,int rowIndex){
		//If the first row's file name is nothing, the table must have no files in.
		//ignore the null table.
		String fileName = (String)(table.getValueAt(0, 1));
		if(!fileName.equals("")){
			DefaultTableModel df = (DefaultTableModel) table.getModel();
			df.removeRow(rowIndex);
		}
	}
	
	/**
	 * update UI of the file receive table and send the pal to blinking list in mainframe when 
	 * the peer sent files.
	 */
	public void receiveFile(){
		this.UpdateFileRcvTable();
		this.mainDlg.AnimatePal(pal);
	}
	
	/**
	 * Save all files in file receive table to the configged folder.
	 */
	public void saveAllFile(){
		saveAllFile(mainDlg.configer.fileSavePath);
	}
	
	/**
	 * Save all files in file receive table to the specified folder.
	 */
	public void saveAllFile(String SavePath){
		TableModel tableModel = table_FileReceive.getModel();
		for(int rowIndex = 0; rowIndex < tableModel.getRowCount(); rowIndex++){
			FileInfo fileInfo = (FileInfo)(tableModel.getValueAt(rowIndex, 3));
			String saveName = SavePath + File.separator + fileInfo.filepath;
			//String saveName = System.getProperty("user.home") + File.separator + fileInfo.filepath;
			if (Integer.valueOf(fileInfo.fileattr,16) ==StaticConsts.IPMSG_FILE_REGAR){
				FileReceiver fReceive = new FileReceiver(fileInfo,saveName);
				new Thread(fReceive).start();
			}else{
				DirReceiver dReceive = new DirReceiver(fileInfo,saveName);
				new Thread(dReceive).start();
			}
		}
	}
	
	/**
	 * Update UI of the file receive table and send the pal to blinking list in mainframe when 
	 * refuse to receive all files in the receive table.
	 * Clear the receive file list.
	 */
	public void refuseAllFile(){
		rcvFileList.clear();
		UpdateFileRcvTable();
	}
	/**
	 * Set JTable columns width
	 * @param table
	 * @param columnIndex
	 * @param width
	 */
	public void setTableColumnWidth(JTable table,int columnIndex,int width){
		TableColumnModel columns = table.getColumnModel(); 
		columns.getColumn(columnIndex).setPreferredWidth(width);
		columns.getColumn(columnIndex).setMaxWidth(width);
		columns.getColumn(columnIndex).setMinWidth(width);
		columns.getColumn(columnIndex).setWidth(width);
		table.getTableHeader().getColumnModel().getColumn(columnIndex).setMaxWidth(width); 
		table.getTableHeader().getColumnModel().getColumn(columnIndex).setMinWidth(width);
	}
	
	/**
	 * Set the progress of file receive progress bar.
	 */
	public void setFileReceiveProgressPosition(){
		if(rcvFileList.size() == 0){
			progressBar_FileReceive.setValue(0);
			return;
		}
		long fileToReceiveSize = 0;
		for(FileInfo fileInfo:rcvFileList){
			fileToReceiveSize = fileToReceiveSize + fileInfo.filesize;
		}
		int position;
		if(fileToReceiveSize == 0){
			position = 0;
		}else{
			position = (int)(receivedFileSize*100/fileToReceiveSize);
		}
		progressBar_FileReceive.setValue(position);
		//System.out.println("rcvFileList size is :" + rcvFileList.size());
	}
	
	/**
	 * Set the progress of file send progress bar.
	 */
	public void setFileSendProgressPosition(){
		if(sendFileList.size() == 0){
			progressBar_FileSend.setValue(0);
			return;
		}
		long fileToSendSize = 0;
		long fileSentSize = 0;
		for(FileInfo fileInfo:sendFileList){
			fileToSendSize = fileToSendSize + fileInfo.filesize;
			fileSentSize = fileSentSize + fileInfo.transmittedSize;
		}
		int position;
		if(fileToSendSize == 0){
			position = 0;
		}else{
			position = (int)(fileSentSize*100/fileToSendSize);
		}
		progressBar_FileSend.setValue(position);
	}
	
	/**
	 * user define data model that not allow to edit table cell.
	 * @author cwll<cwll2009@126.com>
	 *
	 */
	class noEditTableModel extends DefaultTableModel {

		public noEditTableModel(Object[][] data, Object[] columnNames) {
			super(data, columnNames);// 这里一定要覆盖父类的构造方法，否则不能实例myTableModel
		}

		public boolean isCellEditable(int row, int column) {
			return false;// 父类的方法里面是 return true的，所以就可以编辑了~~~
		}
	}
	
	/**
	 * user define TableCellRenderer that can display image in table cell.
	 * @author cwll<cwll2009@126.com>
	 *
	 */
	class ImageTableCellRenderer extends DefaultTableCellRenderer{
		private static final long serialVersionUID = 1L;
		@Override
		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, 
				boolean hasFocus, int row, int column){
			DefaultTableCellRenderer defaultRenderer=new DefaultTableCellRenderer();
			JLabel renderer=(JLabel)defaultRenderer.getTableCellRendererComponent(table, value,isSelected,
					hasFocus, row, column);
			if(value == null){
				return renderer;
			}
			if(value instanceof ImageIcon){
				renderer.setIcon((ImageIcon) value);
				renderer.setText("");
			}
			if(value instanceof FileInfo){
				renderer.setText("");
			}
			return  renderer;
		}
		public ImageTableCellRenderer(){
			
		}
	}
	
	/**
	 * Update file transmit progress 
	 * @author cwll<cwll2009@126.com>
	 *
	 */
	class FileReceiveUIUpdate implements Runnable{
		public void run(){
            while(true){
            	try{
/*            	    Thread thread = Thread.currentThread();
            	    thread.sleep(200);//暂停10秒后程序继续执行
*/            	    Thread.sleep(200);
					setFileReceiveProgressPosition();
					setFileSendProgressPosition();
            	}catch (InterruptedException e) {
            	    e.printStackTrace();
            	}
            }
		}
	}
	
	/**
	 * Append a message to chat history after file receive complete.
	 * @param saveName
	 * @param sendName
	 */
	public void fileReceiveCompleteHint(String saveName,String sendName){
		/*File saveFile = new File(saveName);
		String Msg = "File " + sendName + " receive complete. File saved as ";
		Msg = Msg + saveFile.getName();
		Msg = Msg + " in " + saveFile.getParent() + " .";
		Msg = Msg + "<a href=\"" + saveFile.getParent() + "\" target=\"_blank\">Open saved folder</a>";*/
		String Msg = sendName + ";`;`" + saveName;
		//System.out.println("received file is :" + Msg);
		appendMsgToHistory(Msg,IPMSG_MSG_TYPE_RECEIVE_FILE);
	}
	
	/**
	 * Append a message to chat history after file send complete.
	 * @param fileInfo the send file's file  info 
	 */
	public void fileSendCompleteHint(FileInfo fileInfo){
		String Msg = "File " + fileInfo.filepath + " send complete. ";
		appendMsgToHistory(Msg,IPMSG_MSG_TYPE_SEND_FILE);
	}
	
	/**
	 * The file  receive thread  function class.
	 * @author cwll<cwll2009@126.com>
	 *
	 */
    class FileReceiver implements Runnable{
    	FileInfo fileInfo = null;
    	String saveName = null;
    	Socket socket = null;
    	
    	public FileReceiver(FileInfo fileInfo,String saveName){
    		this.fileInfo = fileInfo;
    		this.saveName = saveName;
    	}
    	
    	public void run(){
    		byte[] buffer = new byte[1024];
    		try{
    			this.socket = new Socket(InetAddress.getByName(pal.ipv4), StaticConsts.IPMSG_PORT);
    			InputStream ips =  socket.getInputStream();
    			OutputStream ops =  socket.getOutputStream();
    			String header = Utils.MakeCommand(StaticConsts.IPMSG_GETFILEDATA/*, mainDlg.PacketNum*/);
    			//mainDlg.PacketNum++;
    			String tcpRequest = header + Integer.toHexString(Integer.valueOf(this.fileInfo.packetn));
    			tcpRequest = tcpRequest + ":" + Integer.toHexString(Integer.valueOf(this.fileInfo.fileid));
    			//file_offset=0
    			tcpRequest = tcpRequest + ":0";
    			//System.out.println("tcp request send is : "+tcpRequest);

    			long receivedBytes = 0;
    			int readBytes = 1;
    			long fileSize = this.fileInfo.filesize;
				File file = new File(this.saveName);
				if(file.exists()){
/*					this.saveName = this.saveName + "(copy)";
					file = new File(this.saveName);*/
					this.saveName = Utils.generateFileName(this.saveName);
					file = new File(this.saveName);
				}
				file.createNewFile(); 
				FileOutputStream filewriter = new FileOutputStream(file);
				ops.write(tcpRequest.getBytes(),0,tcpRequest.getBytes().length);
    			while(receivedBytes < fileSize){
    				readBytes = ips.read(buffer, 0, buffer.length);
    				receivedBytes = receivedBytes + readBytes;    				
    				filewriter.write(buffer, 0, readBytes); 
    				receivedFileSize = receivedFileSize + readBytes;
    				this.fileInfo.transmittedSize = this.fileInfo.transmittedSize + readBytes;
    				if(this.fileInfo.transmittedSize ==  this.fileInfo.filesize){
    					removeFileFromTable(table_FileReceive,this.fileInfo,3);
    					rcvFileList.remove(this.fileInfo);
    				}
    			}
    			//this.socket.close();
    			//UpdateFileRcvUI();
				filewriter.flush();
				filewriter.close(); 
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    		// add a message to history
    		fileReceiveCompleteHint(this.saveName,fileInfo.filepath);
    	}
    	
    }
    
	/**
	 * The dir  receive thread  function class.
	 * @author cwll<cwll2009@126.com>
	 *
	 */
    class DirReceiver implements Runnable{
    	FileInfo fileInfo = null;
    	String saveName = "";
    	String saveDir = "";
    	//boolean isRootDir = true;
		Socket socket;
		InputStream ips;
		OutputStream ops;
		//File fileTmp;

		char[] charBuffer = new char[1024];
    	
    	public DirReceiver(FileInfo fileInfo,String saveName){
    		this.fileInfo = fileInfo;
    		this.saveName = saveName;
    		File file = new File(this.saveName);
    		this.saveDir = file.getParent();
    	}
    	
    	public void run(){
    		String savedName = "";
    		byte[] byteBuffer = new byte[1024];
    		try{
				socket = new Socket(InetAddress.getByName(pal.ipv4),StaticConsts.IPMSG_PORT);
				ips = socket.getInputStream();
				ops = socket.getOutputStream();
				String requestHeader = Utils.MakeCommand(StaticConsts.IPMSG_GETDIRFILES);
				// mainDlg.PacketNum++;
				String tcpRequest = requestHeader + Integer.toHexString(Integer.valueOf(this.fileInfo.packetn));
				tcpRequest = tcpRequest	+ ":" + Integer.toHexString(Integer.valueOf(this.fileInfo.fileid));
				tcpRequest = tcpRequest + ":0";
				//System.out.println("tcp request send is : " + tcpRequest);

				ops.write(tcpRequest.getBytes(), 0,	tcpRequest.getBytes().length);
				ops.flush();
				//feiQ send a 1460 bytes of 0x00 and 156 bytes of 0x00 
				//before send dir data
				if(pal.version.indexOf("lbt")>-1){
					Utils.readSpecifiedBytes(ips,byteBuffer,1024); 
					Utils.readSpecifiedBytes(ips,byteBuffer,436);
					Utils.readSpecifiedBytes(ips,byteBuffer,1024); 
					Utils.readSpecifiedBytes(ips,byteBuffer,436);
					Utils.readSpecifiedBytes(ips,byteBuffer,156);
				}

				String header = readHeader(ips);
				
				File file = new File(this.saveName);
				while (file.exists()) {
					this.saveName = Utils.generateFileName(this.saveName);
					file = new File(this.saveName);
				}
				savedName = this.saveName;
				file.mkdirs();
				//saveDir = file.getParent();
				this.ReceiveData();
    		}catch(Exception e){
    			//System.out.println("exception!");
    			e.printStackTrace();
    		}
			//add a message to history
    		fileReceiveCompleteHint(this.saveName,fileInfo.filepath);
    	}
    	
    	/**
    	 * Receive dir structure and files  recursively 
    	 */
       	private void ReceiveData(){
    		byte[] byteBuffer = new byte[1024];
    		int readBytes;
    		boolean isTerminated = false;
    		File file;
    		try{
    		while(!isTerminated){
    			String header = readHeader(ips);
				//bufferStr = new String(bufHeader);
				//System.out.println("header is : " + header);
				String fileName = header.split(":")[0];
				int fSize = Integer.valueOf(header.split(":")[1], 16);
				int fileAttr =  Integer.valueOf(header.split(":")[2], 16);
				//System.out.println("file is : " + fileName +"*" + fSize +"*" + fileAttr);
				if(fileAttr == StaticConsts.IPMSG_FILE_REGAR) {
					this.saveName = this.saveName + "/" + fileName;
					file = new File(this.saveName);
					FileOutputStream fos = new FileOutputStream(file);
					//OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fos);
					int rcvdBytes = 0;
					while(rcvdBytes < fSize){
						if((rcvdBytes+byteBuffer.length) < fSize){
							readBytes = ips.read(byteBuffer, 0, byteBuffer.length);
						}else{
							readBytes = ips.read(byteBuffer, 0, fSize - rcvdBytes);
						}
						rcvdBytes = rcvdBytes + readBytes;
						this.fileInfo.transmittedSize = rcvdBytes;
						//System.out.println("line 1085 readBytes is : " + readBytes);
						//System.out.println("" + fileName + " rcvdBytes is : " + rcvdBytes);
						//System.out.println("" + fileName + " fSize is : " + fSize);
						fos.write(byteBuffer, 0, readBytes);
					}
					this.saveName = file.getParent();
					fos.close();
				}else if(fileAttr == StaticConsts.IPMSG_FILE_DIR){
					this.saveName = this.saveName + "/" + fileName;
					file = new File(this.saveName);
					file.mkdir();
				}else if(fileAttr == StaticConsts.IPMSG_FILE_RETPARENT){
					file = new File(this.saveName); 
					this.saveName = file.getParent();
					if(this.saveName.equals(this.saveDir)){
    					removeFileFromTable(table_FileReceive,this.fileInfo,3);
    					rcvFileList.remove(this.fileInfo);
						return;
					}
				}else{
					System.out.println("Unkow file attribute");
				}
    		}

    	}catch(Exception e){}
    	}
    	
       	/**
       	 * Read file header from stream. The file header format is like:
       	 * header-size:filename:file-size:fileattr[:extend-attr=val1[,val2...][:extend-attr2=...]]:
       	 * The header-size is a 4 byte hex number.
       	 * @param inputStream  The stream send by pal.
       	 * @return the header string from the filename section, for example:
       	 * filename:file-size:fileattr[:extend-attr=val1[,val2...][:extend-attr2=...]]:
       	 */
    	public String  readHeader(InputStream inputStream){
    		String header;
    		byte[] bufHeaderSize = new byte[5];
			try {
				inputStream.read(bufHeaderSize, 0, 5);
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			header = new String(bufHeaderSize);
			
			int headerSize = Integer.valueOf(header.split(":")[0],16);
			//System.out.println("header size is : " + header + "---" + headerSize);
			byte[] bufHeader = new byte[headerSize - 5];
    		int readBytes = 0;
			try {
				readBytes = inputStream.read(bufHeader, 0,headerSize - 5);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				header = new String(bufHeader,"GB18030");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//System.out.println("header  is : " + header);
    		return header;
    	}
    }
    
}

